package geppetto.cat.alignments.output;


import geppetto.cat.alignments.Alignment;
import geppetto.cat.alignments.AlignmentEvaluator;
import geppetto.cat.alignments.AlignmentsSet;
import geppetto.cat.corpus.BilingualCorpus;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;



public class AlignerOutput {

	// This class defines ways to otput alignments
	public static void output(Alignment alignment, BilingualCorpus corpus,
			PrintStream out) {
		int sentenceNumber = alignment.getSentenceNumber();
		byte sourceSentence = alignment.getSentenceSource();
		out.println("Sentence " + alignment._sentenceNumber);
		for (int j = 0; j < alignment.getSourceLenght(); j++) {
			for (int i = 0; i < alignment.getForeignLenght(); i++) {
				out.print(alignment.getPrintSymbol(j, i));
			}
			out.println(" # "
					+ corpus.getSourceWord(sentenceNumber, sourceSentence, j));

		}
		for (int i = 0; i < alignment.getForeignLenght() + 1; i++) {
			out.print(" # ");
		}
		out.println();
		// detect maximum lenght of word in foreign sentence
		int max = 0;
		for (int i = 0; i < alignment.getForeignLenght(); i++) {
			int size = corpus.getForeignWord(sentenceNumber, sourceSentence, i)
					.length();
			if (size > max)
				max = size;
		}
		for (int i = 0; i < max + 1; i++) {
			for (int j = 0; j < alignment.getForeignLenght(); j++) {
				String word = corpus.getForeignWord(sentenceNumber,
						sourceSentence, j);
				if (word.length() > i) {
					out.print(" " + word.substring(i, i + 1) + " ");
				} else {
					out.print("   ");
				}
			}
			out.println();
		}

	}

	
	public static void output(Alignment alignment, PrintStream out) {
		out.println("Sentence " + alignment._sentenceNumber);
		for (int j = 0; j < alignment.getSourceLenght(); j++) {
			for (int i = 0; i < alignment.getForeignLenght(); i++) {
				out.print(alignment.getPrintSymbol(j, i));
			}
			out.println(" # "+ j);

		}
		for (int i = 0; i < alignment.getForeignLenght() + 1; i++) {
			out.print(" # ");
		}
		out.println();
		// detect maximum lenght of word in foreign sentence
		for (int i = 0; i < alignment.getForeignLenght(); i++) {
			out.print(" "+i+" ");
		}
		out.println();
	}

	public static void outputGold(Alignment alignment, BilingualCorpus corpus,
			PrintStream out) throws UnsupportedEncodingException {
		int sentenceNumber = alignment.getSentenceNumber();
		byte sourceSentence = alignment.getSentenceSource();
		out.println("Gold Alignment for Sentence " + alignment._sentenceNumber);
		for (int j = 0; j < alignment.getSourceLenght(); j++) {
			for (int i = 0; i < alignment.getForeignLenght(); i++) {
				if (alignment.isPossible(j, i)) {
					out.print("[ ]");
				} else if (alignment.isSure(j, i)) {
					out.print("( )");
				} else {
					out.print("   ");
				}
			}
			out.println(" # "
					+ corpus.getSourceWord(sentenceNumber, sourceSentence, j));

		}
		for (int i = 0; i < alignment.getForeignLenght() + 1; i++) {
			out.print(" # ");
		}
		out.println();
		// detect maximum lenght of word in foreign sentence
		int max = 0;
		for (int i = 0; i < alignment.getForeignLenght(); i++) {
			int size = corpus.getForeignWord(sentenceNumber, sourceSentence, i)
					.length();
			if (size > max)
				max = size;
		}
		for (int i = 0; i < max + 1; i++) {
			for (int j = 0; j < alignment.getForeignLenght(); j++) {
				String word = corpus.getForeignWord(sentenceNumber,
						sourceSentence, j);
				if (word.length() > i) {
					out.print(" " + word.substring(i, i + 1) + " ");
				} else {
					out.print("   ");
				}
			}
			out.println();
		}

	}

	public static void outputWithGold(Alignment alignment, Alignment gold,
			BilingualCorpus corpus, PrintStream out) {
		int sentenceNumber = alignment.getSentenceNumber();
		byte sourceSentence = alignment.getSentenceSource();
		out.println("Alignment and Gold Alignment for "
				+ alignment._sentenceNumber);
		out.println();
		out
				.println("( ) Sure Alignments  [ ] Possible Aligments  X  Predicted Alignments");
		out.println();
		for (int j = 0; j < alignment.getSourceLenght(); j++) {
			for (int i = 0; i < alignment.getForeignLenght(); i++) {
				if (alignment.hasPosition(j, i)) {
					if (gold.isPossible(j, i)) {
						out.print("[X]");
					} else if (gold.isSure(j, i)) {
						out.print("(X)");
					} else {
						out.print(" X ");
					}
				} else {
					if (gold.isPossible(j, i)) {
						out.print("[ ]");
					} else if (gold.isSure(j, i)) {
						out.print("( )");
					} else {
						out.print("   ");
					}
				}
			}
			out.println(" # "
					+ corpus.getSourceWord(sentenceNumber, sourceSentence, j));

		}
		for (int i = 0; i < alignment.getForeignLenght() + 1; i++) {
			out.print(" # ");
		}
		out.println();
		// detect maximum lenght of word in foreign sentence
		int max = 0;
		for (int i = 0; i < alignment.getForeignLenght(); i++) {
			int size = corpus.getForeignWord(sentenceNumber, sourceSentence, i)
					.length();
			if (size > max)
				max = size;
		}
		for (int i = 0; i < max + 1; i++) {
			for (int j = 0; j < alignment.getForeignLenght(); j++) {
				String word = corpus.getForeignWord(sentenceNumber,
						sourceSentence, j);
				if (word.length() > i) {
					out.print(" " + word.substring(i, i + 1) + " ");
				} else {
					out.print("   ");
				}
			}
			out.println();
		}
		System.out.println(AlignmentEvaluator.evaluate(alignment, gold));
		out.println();
	}

	public static void outputWithGold(Alignment alignment, Alignment gold,
			BilingualCorpus corpus, PrintStream out, float[] results) {
		int sentenceNumber = alignment.getSentenceNumber();
		byte sourceSentence = alignment.getSentenceSource();
		out.println("Alignment and Gold Alignment for "
				+ alignment._sentenceNumber);
		out.println();
		out
				.println("( ) Sure Alignments  [ ] Possible Aligments  X  Predicted Alignments");
		out.println();
		for (int j = 0; j < alignment.getSourceLenght(); j++) {
			for (int i = 0; i < alignment.getForeignLenght(); i++) {
				if (alignment.hasPosition(j, i)) {
					if (gold.isPossible(j, i)) {
						out.print("[X]");
					} else if (gold.isSure(j, i)) {
						out.print("(X)");
					} else {
						out.print(" X ");
					}
				} else {
					if (gold.isPossible(j, i)) {
						out.print("[ ]");
					} else if (gold.isSure(j, i)) {
						out.print("( )");
					} else {
						out.print("   ");
					}
				}
			}
			out.println(" # "
					+ corpus.getSourceWord(sentenceNumber, sourceSentence, j));

		}
		for (int i = 0; i < alignment.getForeignLenght() + 1; i++) {
			out.print(" # ");
		}
		out.println();
		// detect maximum lenght of word in foreign sentence
		int max = 0;
		for (int i = 0; i < alignment.getForeignLenght(); i++) {
			int size = corpus.getForeignWord(sentenceNumber, sourceSentence, i)
					.length();
			if (size > max)
				max = size;
		}
		for (int i = 0; i < max + 1; i++) {
			for (int j = 0; j < alignment.getForeignLenght(); j++) {
				String word = corpus.getForeignWord(sentenceNumber,
						sourceSentence, j);
				if (word.length() > i) {
					out.print(" " + word.substring(i, i + 1) + " ");
				} else {
					out.print("   ");
				}
			}
			out.println();
		}
		out.println("Precision " + results[0] + " Recall " + results[1]
				+ " AER " + results[2]);
		out.println("Number of aligned points "
				+ alignment.numberOfAlignedPoints());
		out
				.println("Number of null aligned words"
						+ alignment.getNumberNulls());
		int[] lonelyPoints = alignment.getLonelyPoints(gold, Alignment.MASK);
		out.println("Number of lonely words correct " + lonelyPoints[0]
				+ "Incorrect " + lonelyPoints[1]);
		out.println("Distance to diagonal " + alignment.distanceToDiagonal());
		out.println();
		out.println();
	}

	public static void outputAlignments(ArrayList<Alignment> al,
			BilingualCorpus corpus, String file)
			throws UnsupportedEncodingException, FileNotFoundException {
		PrintStream examples = new PrintStream(new FileOutputStream(file),
				true, "ISO8859_1");
		for (int i = 0; i < al.size(); i++) {
			AlignerOutput.output(al.get(i), corpus, examples);
			examples.println();
			examples.println();
			examples.println();
		}
		examples.close();
	}

	public static void printHansardFormat(AlignmentsSet al, String file)
			throws UnsupportedEncodingException, FileNotFoundException {
		PrintStream alignments = new PrintStream(new FileOutputStream(file),
				true, "ISO8859_1");
		for (Alignment a : al.getAlignments()) {
			alignments.print(a.toHazardFormat());
		}
		alignments.close();
	}

	public static void printGizaFormat(ArrayList<Alignment> al, String file,
			BilingualCorpus corpus) throws UnsupportedEncodingException,
			FileNotFoundException {
		PrintStream alignments = new PrintStream(new FileOutputStream(file),
				true, "UTF-8");
		for (Alignment a : al) {
			alignments.print(a.toGizaFormat(corpus));
		}
		alignments.close();
	}

	public static void printMosesFormat(AlignmentsSet al,
			BilingualCorpus corpus, String alignmentDir, String alignmentName)
			throws UnsupportedEncodingException, FileNotFoundException {
		PrintStream alignments = new PrintStream(new FileOutputStream(
				alignmentDir + alignmentName), true, "UTF-8");
		PrintStream sourceS = new PrintStream(new FileOutputStream(alignmentDir
				+ "aligned.0." + corpus.getSourceSufix()), true, "UTF-8");
		PrintStream foreignS = new PrintStream(new FileOutputStream(
				alignmentDir + "aligned.0." + corpus.getForeignSufix()), true,
				"UTF-8");
		for (Alignment a : al.getAlignments()) {
			String[] data = a.toMosesFormat(corpus);
			alignments.println(data[0]);
			sourceS.println(data[1]);
			foreignS.println(data[2]);
		}
		alignments.close();
	}

}
